package com.wm.blog_admin.service;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wm.blog_admin.controller.resp.RecommendResp;
import com.wm.blog_admin.dao.TRecommendDAO;
import com.wm.blog_admin.dao.TTagDAO;
import com.wm.blog_admin.domain.RecommendDo;
import com.wm.blog_admin.feign.PictureFeignClient;
import com.wm.blog_admin.query.TRecommendQuery;
import com.wm.blog_common.base.BeanUtils;
import com.wm.blog_common.bean.PageHelper;
import com.wm.blog_common.bean.QueryPage;
import com.wm.blog_common.constatnt.ErrorConstant;
import com.wm.blog_common.domain.TRecommendDO;
import com.wm.blog_common.entity.TFile;
import com.wm.blog_common.entity.TRecommend;
import com.wm.blog_common.entity.TTag;
import com.wm.blog_common.enums.BlogTopEnum;
import com.wm.blog_common.exception.BusinessException;
import com.wm.blog_common.result.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 推荐 服务实现类
 * </p>
 *
 * @author wm_yu
 * @since 2020-04-15
 */
@Service
public class TRecommendService{
    @Autowired
    private TRecommendDAO tRecommendDAO;

    @Autowired
    private PictureFeignClient pictureFeignClient;

    @Autowired
    private TTagDAO tTagDAO;



    /**
     * 根据ID查询
     * @param id
     * @return
     */
    public Result<TRecommendDO> selectById(Long id){
        return Result.success(BeanUtils.copyProperties(tRecommendDAO.getById(id),TRecommendDO.class));
    }

    /**
    * 根据ID删除
    * @param id
    * @return
    */
    public Result deleteById(Long id){
        return tRecommendDAO.removeById(id)?Result.success():Result.failure();
    }

    /**
    * 添加
    * @param tRecommend
    * @return
    */
    public Result insert(TRecommend tRecommend){
        return tRecommendDAO.save(tRecommend)?Result.success():Result.failure();
    }

    /**
    * 修改
    * @param tRecommend
    * @return
    */
    public Result update(TRecommend tRecommend){
        return tRecommendDAO.updateById(tRecommend)?Result.success():Result.failure();
    }

    /**
    * 统计总数
    *
    * @param query
    * @return
    */
    public Result<Integer> count(TRecommendQuery query) {
        return Result.success(tRecommendDAO.count(this.combineQuery(query)));
    }

    /**
    * 列表查询
    * @param query
    * @return
    */
    public Result<List<TRecommendDO>> list(TRecommendQuery query){
        return Result.success(BeanUtils.copyListProperties(tRecommendDAO.list(this.combineQuery(query)),TRecommendDO.class));
    }
    /**
    * 分页查询
    * @param page
    * @return
    */
    public Result<Page<RecommendResp>> page(QueryPage page, TRecommendQuery query){
        Page<RecommendDo> doPage  = PageHelper.newPage(tRecommendDAO.recommendPage(page,query));
        Page<RecommendResp> respPage = PageHelper.newPage(page, Collections.EMPTY_LIST);
        if(!CollectionUtils.isEmpty(doPage.getRecords())){
            List<RecommendDo> records = doPage.getRecords();
            //图片id
            List<Long> fileIdList = records
                    .stream()
                    .map(RecommendDo::getFileId)
                    .distinct()
                    .collect(Collectors.toList());

           //图片map
            Map<Long, String> picMap = Optional
                    .ofNullable(pictureFeignClient.getByIdList(fileIdList))
                    .map(Result::getData)
                    .orElse(Collections.emptyList())
                    .stream()
                    .collect(Collectors.toMap(TFile::getId, TFile::getPicUrl));

            //标签id
            List<Long> tagIdList = records
                    .stream()
                    .map(RecommendDo::getTagId)
                    .distinct()
                    .collect(Collectors.toList());

            //tag map
            Map<Long, String> tagMap = Optional
                    .ofNullable(tTagDAO.listByIds(tagIdList))
                    .orElse(Collections.emptyList())
                    .stream()
                    .collect(Collectors.toMap(TTag::getId, TTag::getContent));




            List<RecommendResp> resps = Optional
                    .ofNullable(BeanUtils.copyListProperties(records, RecommendResp.class))
                    .orElse(Collections.emptyList());
            List<RecommendResp> respList = resps.stream().peek(x -> {
                x.setPicUrl(picMap.getOrDefault(x.getFileId(), null));
                x.setTagName(tagMap.getOrDefault(x.getTagId(), null));
            }).collect(Collectors.toList());
            //数据排序   按照置顶+orderNum排序
            List<RecommendResp> sortList = respList
                    .stream()
                    .sorted(Comparator.comparing(RecommendResp::getTop)
                            .thenComparing(RecommendResp::getOrderNum))
                    .collect(Collectors.toList());
            respPage.setRecords(sortList);
        }
        return Result.success(respPage);
    }

    /**
    * 组装查询条件
    *
    * @param query
    * @return
    */
    private QueryWrapper<TRecommend> combineQuery(TRecommendQuery query) {
        QueryWrapper<TRecommend> wrapper = new QueryWrapper<>();
        //todo 查询条件 wrapper.eq("字段名","值")
        return wrapper;
    }

    /**
     * 推荐置顶
     * @param id
     * @return
     */
    public Result topRecommend(Long id) {
        Optional.ofNullable(id).orElseThrow(() -> new BusinessException(ErrorConstant.BLOG_RECOMMEND_ID_EMPTY));
        TRecommend recommend = new TRecommend();
        //查询已经置顶的博客中,排序最小+排序最大的推荐数字(排除掉自身)
        TRecommendQuery query = new TRecommendQuery();
        query.setId(id);
        query.setTop(BlogTopEnum.YES.getValue());
        RecommendDo recommendDo = Optional.ofNullable(tRecommendDAO.recommendMaxMinOrder(query)).orElse(new RecommendDo());
        Integer orderNum = Optional.ofNullable(recommendDo.getMinOrder()).orElse(0);
        recommend.setId(id);
        recommend.setTop(BlogTopEnum.YES.getValue());
        recommend.setOrderNum(orderNum - 1);
        return tRecommendDAO.updateById(recommend) ? Result.success():Result.failure();
    }

    public Result deleteRecommend(Long id) {
        Optional.ofNullable(id).orElseThrow(() -> new BusinessException(ErrorConstant.BLOG_RECOMMEND_ID_EMPTY));
        //删除推荐
        return tRecommendDAO.removeById(id) ? Result.success():Result.failure();
    }
}







